<?php

namespace App\System\Logic;

use App\System\ErrorCode\LError;
use App\System\Exception\LException;
use App\System\Service\HeiRoleMenuService;
use App\System\Service\HeiTenantMenuService;
use App\System\Utils\AuthUser;
use Hyperf\Cache\Annotation\Cacheable;
use Hyperf\Di\Annotation\Inject;
use App\System\Service\HeiUserService;
use Haozing\FastCore\Constants\ErrorCode;
use Haozing\FastCore\Exception\CommonException;
use Qbhy\HyperfAuth\Authenticatable;

class HeiUserLogic
{
    #[Inject]
    protected HeiUserService $heiUserService;

    #[Inject]
    protected HeiTenantMenuService $heiTenantMenuService;

    #[Inject]
    protected HeiRoleMenuService $heiRoleMenuService;

    /**
     * 新增逻辑
     * @param array $params
     * @return array
     */
    public function add(array $params = []): array
    {
        // 参数处理
        $data = [
            'username' => $params['username'] ?? '',
            'password' => $params['password'] ?? '123456',
            'user_type' => $params['user_type'] ?? '',
            'nickname' => $params['nickname'] ?? '',
            'phone' => $params['phone'] ?? '',
            'email' => $params['email'] ?? '',
            'avatar' => $params['avatar'] ?? '',
            'signed' => $params['signed'] ?? '',
            'dashboard' => $params['dashboard'] ?? '',
            'dept_id' => $params['dept_id'] ?? 0,
            'tenant_id' => $params['tenant_id'] ?? 0,
            'status' => $params['status'] ?? 0,
            'login_ip' => $params['login_ip'] ?? '',
            'login_time' => $params['login_time'] ?? '',
            'backend_setting' => $params['backend_setting'] ?? '',
            'created_by' => $params['created_by'] ?? 0,
            'updated_by' => $params['updated_by'] ?? 0,
            'created_at' => date('Y-m-d H:i:s'),
            'remark' => $params['remark'] ?? '',

        ];
        /** @var  Authenticatable $user */
        $user = $this->heiUserService->getModel()->where('username', $data['username'])->first();
        //查询用户是否存在，如果用户存在，转为数组
        if ($user) {
            throw new  LException(LError::$params_invalid,'用户已存在');
        }
        $data['password'] = authUser()->getJwt()->getEncrypter()->signature($data['password']);
        $data = $this->heiUserService->addOne($data);
        if (!$data) {
            throw new CommonException(ErrorCode::BAD_REQUEST,'新增失败');
        }
        return [];

    }

    /**
     * 更新逻辑
     * @param array $params
     * @return int
     */
    public function update(array $params = []): int
    {
        // 条件参数处理
        $where = [];
        // 更新数据参数处理
        $data = [];
        if (isset($params['username'])) {
            $data['username'] = $params['username'];
        }
        if (isset($params['password'])) {
            $data['password'] = $params['password'];
        }
        if (isset($params['user_type'])) {
            $data['user_type'] = $params['user_type'];
        }
        if (isset($params['nickname'])) {
            $data['nickname'] = $params['nickname'];
        }
        if (isset($params['phone'])) {
            $data['phone'] = $params['phone'];
        }
        if (isset($params['email'])) {
            $data['email'] = $params['email'];
        }
        if (isset($params['avatar'])) {
            $data['avatar'] = $params['avatar'];
        }
        if (isset($params['signed'])) {
            $data['signed'] = $params['signed'];
        }
        if (isset($params['dashboard'])) {
            $data['dashboard'] = $params['dashboard'];
        }
        if (isset($params['dept_id'])) {
            $data['dept_id'] = $params['dept_id'];
        }
        if (isset($params['tenant_id'])) {
            $data['tenant_id'] = $params['tenant_id'];
        }
        if (isset($params['status'])) {
            $data['status'] = $params['status'];
        }
        if (isset($params['login_ip'])) {
            $data['login_ip'] = $params['login_ip'];
        }
        if (isset($params['login_time'])) {
            $data['login_time'] = $params['login_time'];
        }
        if (isset($params['backend_setting'])) {
            $data['backend_setting'] = $params['backend_setting'];
        }
        if (isset($params['created_by'])) {
            $data['created_by'] = $params['created_by'];
        }
        if (isset($params['updated_by'])) {
            $data['updated_by'] = $params['updated_by'];
        }
        if (isset($params['created_at'])) {
            $data['created_at'] = $params['created_at'];
        }
        if (isset($params['remark'])) {
            $data['remark'] = $params['remark'];
        }

        // TODO 逻辑处理
        $data = $this->heiUserService->updateByWhere($where,$data);
        if (!$data) {
            throw new CommonException(ErrorCode::BAD_REQUEST,'修改失败');
        }
        return $data;
    }

    /**
     * 删除逻辑
     * @param array $params
     * @return mixed
     */
    public function delete(array $params = []): array
    {
        // TODO 逻辑处理
        $data = $this->heiUserService->deleteByWhere($params);
        if (!$data) {
            throw new CommonException(ErrorCode::BAD_REQUEST,'删除失败');
        }
        return [];
    }

    /**
     * 详情逻辑
     * @param array $params
     * @return array
     */
    public function detail(array $params = []): array
    {
        // TODO 逻辑处理
        if (!isset($params['id']) ||!$params['id']) {
            throw new CommonException(ErrorCode::INVALID_PARAM,'参数错误');
        }
        $data = $this->heiUserService->getOneById($params['id'],['*']);
        if (!$data) {
            throw new CommonException(ErrorCode::NOT_FOUND,'资源不存在');
        }
        return $data;
    }
    /**
     * 用户详情info
     */
    public function info(array $params = []): array
    {
        /** @var AuthUser $user */
        $user = user();

        if ($uid = $user->getId()) {
            return $this->getCacheInfo((int)$uid);
        }
        throw new LException(LError::$params_invalid,'资源不存在');
    }

    /**
     * 获取缓存用户信息.
     */
    #[Cacheable(prefix: 'loginInfo', value: 'userId_#{id}', ttl: 0)]
    protected function getCacheInfo(int $id): array
    {

        //获取用户信息
        $userInfo = $this->heiUserService->getOneByWhere(['id' => $id]);
        //todo 排除不需要的东西
        $data['user'] = $userInfo;
        //查询用户是否是租户的超级管理员
        $user = authUser();

        if ($user->isSuperAdmin()) {
            $data['menus'] = $this->heiTenantMenuService->getTenantAdminRouterTree();
        }else{
            // 查询用户的角色
            $roleIds = $user->getUserRole();
            $data['menus'] = [];
            if (!empty($roleIds)) {
                //根据id查询角色菜单
                $roleMenus = $this->heiRoleMenuService->getManyByWhere(['role_id','in', $roleIds],['menu_id']);
                //角色菜单去重
                $ids = $this->filterMenuIds($roleMenus);
                $data['menus'] = $this->heiTenantMenuService->getTenantAdminMenuById($ids);
            }
        }
        return $data;
    }
    /**
     * 列表查询逻辑
     * @param array $params
     * @return array
     */
    public function list(array $params = []): array
    {
        // 条件参数处理
        $where = [];
        // 其他参数处理
        $options = [];
        if (isset($params['username']) && $params['username']) {
            $where[] = ['username',$params['username']];
        }
        if (isset($params['password']) && $params['password']) {
            $where[] = ['password',$params['password']];
        }
        if (isset($params['user_type']) && $params['user_type']) {
            $where[] = ['user_type',$params['user_type']];
        }
        if (isset($params['nickname']) && $params['nickname']) {
            $where[] = ['nickname',$params['nickname']];
        }
        if (isset($params['phone']) && $params['phone']) {
            $where[] = ['phone',$params['phone']];
        }
        if (isset($params['email']) && $params['email']) {
            $where[] = ['email',$params['email']];
        }
        if (isset($params['avatar']) && $params['avatar']) {
            $where[] = ['avatar',$params['avatar']];
        }
        if (isset($params['signed']) && $params['signed']) {
            $where[] = ['signed',$params['signed']];
        }
        if (isset($params['dashboard']) && $params['dashboard']) {
            $where[] = ['dashboard',$params['dashboard']];
        }
        if (isset($params['dept_id']) && $params['dept_id']) {
            $where[] = ['dept_id',$params['dept_id']];
        }
        if (isset($params['tenant_id']) && $params['tenant_id']) {
            $where[] = ['tenant_id',$params['tenant_id']];
        }
        if (isset($params['status']) && $params['status']) {
            $where[] = ['status',$params['status']];
        }
        if (isset($params['login_ip']) && $params['login_ip']) {
            $where[] = ['login_ip',$params['login_ip']];
        }
        if (isset($params['login_time']) && $params['login_time']) {
            $where[] = ['login_time',$params['login_time']];
        }
        if (isset($params['backend_setting']) && $params['backend_setting']) {
            $where[] = ['backend_setting',$params['backend_setting']];
        }
        if (isset($params['created_by']) && $params['created_by']) {
            $where[] = ['created_by',$params['created_by']];
        }
        if (isset($params['updated_by']) && $params['updated_by']) {
            $where[] = ['updated_by',$params['updated_by']];
        }
        if (isset($params['created_at']) && $params['created_at']) {
            $where[] = ['created_at',$params['created_at']];
        }
        if (isset($params['remark']) && $params['remark']) {
            $where[] = ['remark',$params['remark']];
        }


        if (isset($params['pageSize']) && $params['pageSize']) {
            $options['pageSize'] = $params['pageSize'];
        }
        // TODO 逻辑处理
        $data = $this->heiUserService->getPage($where,['*'],$options);
        // TODO 数据聚合
        return [
            'total' => $data['total']??0,
            'list' => $data['data']??[],
        ];
    }
    /**
     * 列表查询[简单kv字段]
     * @param array $params
     * @return array
     */
    public function select(array $params = []): array
    {
        // 条件参数处理
        $where = [];
        // 其他参数处理
        $options = [];
        if (isset($params['username']) && $params['username']) {
            $where[] = ['username',$params['username']];
        }
        if (isset($params['password']) && $params['password']) {
            $where[] = ['password',$params['password']];
        }
        if (isset($params['user_type']) && $params['user_type']) {
            $where[] = ['user_type',$params['user_type']];
        }
        if (isset($params['nickname']) && $params['nickname']) {
            $where[] = ['nickname',$params['nickname']];
        }
        if (isset($params['phone']) && $params['phone']) {
            $where[] = ['phone',$params['phone']];
        }
        if (isset($params['email']) && $params['email']) {
            $where[] = ['email',$params['email']];
        }
        if (isset($params['avatar']) && $params['avatar']) {
            $where[] = ['avatar',$params['avatar']];
        }
        if (isset($params['signed']) && $params['signed']) {
            $where[] = ['signed',$params['signed']];
        }
        if (isset($params['dashboard']) && $params['dashboard']) {
            $where[] = ['dashboard',$params['dashboard']];
        }
        if (isset($params['dept_id']) && $params['dept_id']) {
            $where[] = ['dept_id',$params['dept_id']];
        }
        if (isset($params['tenant_id']) && $params['tenant_id']) {
            $where[] = ['tenant_id',$params['tenant_id']];
        }
        if (isset($params['status']) && $params['status']) {
            $where[] = ['status',$params['status']];
        }
        if (isset($params['login_ip']) && $params['login_ip']) {
            $where[] = ['login_ip',$params['login_ip']];
        }
        if (isset($params['login_time']) && $params['login_time']) {
            $where[] = ['login_time',$params['login_time']];
        }
        if (isset($params['backend_setting']) && $params['backend_setting']) {
            $where[] = ['backend_setting',$params['backend_setting']];
        }
        if (isset($params['created_by']) && $params['created_by']) {
            $where[] = ['created_by',$params['created_by']];
        }
        if (isset($params['updated_by']) && $params['updated_by']) {
            $where[] = ['updated_by',$params['updated_by']];
        }
        if (isset($params['created_at']) && $params['created_at']) {
            $where[] = ['created_at',$params['created_at']];
        }
        if (isset($params['remark']) && $params['remark']) {
            $where[] = ['remark',$params['remark']];
        }


        if (isset($params['pageSize']) && $params['pageSize']) {
            $options['pageSize'] = $params['pageSize'];
        }
        // TODO 逻辑处理
        $data = $this->heiUserService->getPage($where,['id','name'],$options);
        // TODO 数据聚合
        return [
            'total' => $data['total']??0,
            'list' => $data['data']??[],
        ];
    }

    public function login(array $params = []): array
    {
        //根据username查询用户信息
        /** @var  Authenticatable $user */
        $user = $this->heiUserService->getModel()->where('username', $params['username'])->first();
        //查询用户是否存在，如果用户存在，转为数组
        if ($user) {
            $userInfo = $user->toArray();
        }else {
            throw new LException(LError::$params_invalid);
        }
        //如果用户存在，并且密码正确
        if (isset($userInfo['password']) && authUser()->checkPassword($params['password'], $userInfo['password'])) {
            //判断用户状态
            if ($userInfo['status'] !== 1) {
                throw new LException(LError::$params_invalid);
            }
        }

        return [
            'token' => authUser()->getToken($user),
            'expire' => authUser()->getJwt()->getTtl(),
        ];
    }

    /**
     * 过滤通过角色查询出来的菜单id列表，并去重.
     */
    protected function filterMenuIds(array &$roleData): array
    {
        $ids = [];
        foreach ($roleData as $val) {
            foreach ($val['menus'] as $menu) {
                $ids[] = $menu['id'];
            }
        }
        unset($roleData);
        return array_unique($ids);
    }
}